package cn.blnp.net.flowable.task.service.introduce;

import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.async.AsyncTaskInvoker;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.FutureJavaDelegate;
import org.springframework.stereotype.Component;

import java.util.concurrent.CompletableFuture;

/**
 * <h3></h3>
 *
 * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
 * @version 1.0
 * @since 2025/5/12 17:21
 */
@Slf4j
@Component
public class MyFutureJavaDelegate implements FutureJavaDelegate {

    /**
     *  <p>
     *  &emsp;&emsp;在流程执行过程中，当流程到达一个FutureJavaDelegate类型的服务任务时，execute()方法会异步执行该任务，并等待任务执行完成后获取返回的Future对象。
     *  通过这个Future对象，afterExecution()方法可以在后续的流程中获取任务执行的结果。
     *  </p>
     *  <p>
     *   &emsp;&emsp;execute()方法中的参数AsyncTaskInvoker是一个接口，通过其submit()方法可使用Flowable维护的公共共享线程池执行异步任务。在submit()方法中通常可以将
     *   一些耗时的复杂逻辑异步执行，并且在执行完成后将结果返回。这里的AsyncTaskInvoker也可以使用自己自定义的ExecutorService，或者从自己服务中返回的CompletableFuture。
     *  </p>
     *  <p>
     *   &emsp;&emsp;afterExecution()方法在异步任务完成后执行，它的参数executionData是执行execute()方法返回的结果。这样可以避免阻塞整个流程的执行，提高流程的执行效率。
     *  </p>
     */

    @Override
    public CompletableFuture execute(DelegateExecution execution, AsyncTaskInvoker taskInvoker) {
        //这里与流程实例是在同一个数据库事务中运行，可以通过execution设置和获取相关数据
        String variable = (String)execution.getVariable("variableName");
        return taskInvoker.submit(()->{
            //这里是在一个新线程中运行，execution不能在这里使用
            //这里没有数据库事务，如果需要事务控制，应该由自己的服务进行管理
            //这里通常用于执行一些比较耗时的复杂逻辑，比如调用外部服务
            return variable;
        });
    }

    @Override
    public void afterExecution(DelegateExecution execution, Object executionData) {
        //executionData参数是execute()方法返回的结果
        //这里与流程实例是在同一个数据库事务中运行，可以通过execution进行一些操作，比如设置变量
        execution.setVariable("result", executionData);
    }
}
